import { toStringTypeCheck } from './toStringTypeCheck';

/**
 * 获取 当前元素 的 指定 祖先 元素 一直找到 BODY 元素结束
 * @param {Element} node  element
 * @param {String} targetStr node | id | class
 */
function getTargetEl(node, targetStr) {
  //   console.log(node, targetStr);
  let search = {
    searchfor: 'id',
    done: false,
    /**
     * @type {HTMLElement}
     */
    domNode: undefined,
  };
  let node0 = node;
  if (targetStr.nodeType == 1) {
    search['searchfor'] = 'node';
    searchParentNode(node0);
  } else {
    let a = ['#', '.'].indexOf(targetStr.slice(0, 1));
    search['searchfor'] = a > -1 ? (a == 0 ? 'id' : 'class') : 'all';

    if (search['searchfor'] == 'all') {
      //填充符号 确保 前一位 有占位
      targetStr = '$' + targetStr;
      search['searchfor'] = 'id';
      searchParentNode(node0);
      if (search['done'] == false) {
        search['searchfor'] = 'class';
        searchParentNode(node0);
      }
    } else {
      searchParentNode(node0);
    }
  }

  function searchParentNode(node) {
    if (node.nodeName == 'BODY') {
      return false;
    }
    if (search['searchfor'] == 'id') {
      if (node.id == targetStr.slice(1, undefined)) {
        search['done'] = true;
        search['searchfor'] = 'id';
        search['domNode'] = node;
      } else {
        node = node.parentNode;
        searchParentNode(node);
      }
    }
    if (search['searchfor'] == 'class') {
      if (node.classList.contains(targetStr.slice(1, undefined))) {
        search['done'] = true;
        search['searchfor'] = 'class';
        search['domNode'] = node;
      } else {
        node = node.parentNode;
        searchParentNode(node);
      }
    }
    if (search['searchfor'] == 'node') {
      if (node == targetStr) {
        search['done'] = true;
        search['searchfor'] = 'class';
        search['domNode'] = node;
      } else {
        node = node.parentNode;
        searchParentNode(node);
      }
    }
  }
  //   if (search['done']) {
  //     node = search['domNode'];
  //   }
  return search;
}

/**
 * 查询 满足 条件 的 祖先元素
 * @param {HTMLElement} element 元素
 * @param {Function} cb 回调函数
 */
function seekElement_callback(element, cb) {
  if (element.nodeName == 'BODY') {
    // console.log('seek arrive body element');
    return null;
  }

  if (!toStringTypeCheck(cb, 'function')) {
    // console.log('seekElement_callback.cb is not a function');
    return null;
  }

  if (cb(element)) {
    return element;
  }

  return seekElement_callback(element.parentNode, cb);
}

/**
 * 查询 指定 class str  的 祖先元素
 * @param {HTMLElement} element
 * @param {string} classStr
 */
function seekElement_class(element, classStr) {
  let cb_class = (node) => {
    if (node.classList.contains(classStr)) {
      return true;
    }
    return false;
  };

  return seekElement_callback(element, cb_class);
}

/**
 * 查询 指定 id str  的 祖先元素
 * @param {HTMLElement} element
 * @param {string} idStr
 */
function seekElement_id(element, idStr) {
  let cb_id = (node) => {
    if (node.id == idStr) {
      return true;
    }
    return false;
  };

  return seekElement_callback(element, cb_id);
}

/**
 * 查询 指定 name 的 元素 集合
 * @param {string} nameStr
 */
function seekElementList_name(nameStr) {
  return document.getElementsByName(nameStr);
}

/**
 * 查询 指定 attribute key = val 祖先元素
 * @param {HTMLElement} element
 * @param {string} specialKey
 * @param {string | undefined} specialValue
 */
function seekElement_attribute(element, specialKey, specialValue) {
  /**
   *
   * @param {HTMLElement} node
   */
  let cb_special = (node) => {
    if (node.hasAttribute(specialKey)) {
      if (specialValue != undefined) {
        if (node.getAttribute(specialKey) == specialValue) {
          return true;
        } else {
          return false;
        }
      }
      return true;
    }
    return false;
  };

  return seekElement_callback(element, cb_special);
}

/**
 * 杂糅式 找寻 相应的 元素 优先 args == 2 id class specialkey || args == 3 specialkey specialValue
 * @param {HTMLElement} element 当前元素
 * @param {string} str0 关键字
 * @param {string} str1 关键字
 */
function seekElement(element, str0, str1) {
  let ret = null;
  let cloneNode;
  let sourceElement = () => {
    cloneNode = element;
  };

  if (str1 != undefined) {
    sourceElement();
    ret = seekElement_attribute(cloneNode, str0, str1);
    return ret;
  }

  let queueDate = {
    data: ['id', 'classL', 'specialKey'],
    id: seekElement_id,
    classL: seekElement_class,
    specialKey: seekElement_attribute,
  };

  let seekQueue = (index) => {
    if (index == queueDate.data.length) {
      return null;
    }
    sourceElement();
    ret = queueDate[queueDate.data[index]](cloneNode, str0);
    if (ret == null) {
      return seekQueue(++index);
    }
    return ret;
  };

  return seekQueue(0);
}

export {
  getTargetEl,
  seekElement,
  seekElement_class,
  seekElement_id,
  seekElement_attribute,
  seekElement_callback,
  seekElementList_name,
};
